package umich.max.geolocation.geonames;

import java.util.HashSet;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.TermQuery;
import org.geonames.FeatureClass;

public class Geonames {
	private static final String geonamesDir = "/home/max/proj/geonames/solr-geonames-read-only/harvester/solr/data/index";
	private static final String admin2Dir = "/home/max/proj/geonames/indeces/admin2";
	private static final String featDir = "/home/max/proj/geonames/indeces/feats";
	private Index geoIndex, featsIndex, adminIndex;

	public Geonames() {
		geoIndex = new Index(geonamesDir, true);
		featsIndex = new Index(featDir, true);
		adminIndex = new Index(admin2Dir, true);

	}
	
	public HashSet<String>  extractStatesFromQuery(String text){
		HashSet<String> states = new HashSet<String>();
		BooleanQuery query = keywordQuery(text);
		List<Document> results = geoIndex.getTopNDocs(query, 8);
		for (Document s : results) {
			states.add(s.get("admin1"));
		}
		return states;
	}

	public void test() {
		BooleanQuery query = keywordQuery("Genesee Park");
//		 BooleanQuery query = cityStateQuery("TX", "San Diego");

		List<Document> r = geoIndex.getTopNDocs(query, 100);
		System.out.println(r.size());
		printFields(r, "basic_name", "admin1", "admin2", "admin3", "admin4");
//		BooleanQuery a1 = convertToAdminQuery(r.get(1));
//		List<Document> res = adminIndex.getTopNDocs(a1, 5);
//		printAll(res);
		// featsIndex.openIndexForReading();
		// BooleanQuery q = featsQuery("S.ML");
		// List<Document> results = featsIndex.getTopNDocs(q, 1);
		// System.out.println(results.size());
		// printAll(results);

	}

	public static void main(String[] args) {
		Geonames g = new Geonames();
		g.test();
	}

	public BooleanQuery featsQuery(String type) {
		BooleanQuery query = new BooleanQuery();
		query.add(new TermQuery(new Term("code", "S.MKT")),
				BooleanClause.Occur.MUST);
		return query;
	}

	public BooleanQuery keywordQuery(String qText) {
		BooleanQuery query = new BooleanQuery();
		String[] queries = qText.split(" ");
		for (int i = 0; i < queries.length; i++) {
			query.add(
					new TermQuery(new Term("basic_name", queries[i]
							.toLowerCase())), BooleanClause.Occur.MUST);
		}
		return query;
	}

	public BooleanQuery cityStateQuery( String state,String c) {
		BooleanQuery query = new BooleanQuery();
		String[] cityParts = c.split(" ");
		for (String city : cityParts){
		query.add(new TermQuery(new Term("basic_name", city.toLowerCase())),
				BooleanClause.Occur.MUST);
		}
		query.add(new TermQuery(new Term("admin1", state)),
				BooleanClause.Occur.MUST);
		return query;
	}

	//
	public BooleanQuery convertToAdminQuery(Document d) {

		BooleanQuery query = new BooleanQuery();

		String country = d.get("country_code");
		if (country != null) {
			query.add(new TermQuery(new Term("country", country)),
					BooleanClause.Occur.MUST);
		}

		String state = d.get("admin1");
		if (state != null) {
			query.add(new TermQuery(new Term("state", state)),
					BooleanClause.Occur.MUST);
		}

		String countyCode = d.get("admin2");
		if (countyCode != null) {
			query.add(new TermQuery(new Term("admin2", countyCode)),
					BooleanClause.Occur.MUST);
		}
		return query;
	}

	public String extractCountyName(Document geonamesResult) {
		BooleanQuery query = convertToAdminQuery(geonamesResult);

		List<Document> reg = adminIndex.getTopNDocs(query, 1);
		Document result = reg.get(0);
		if (result != null)
			return result.get("name");
		else
			return null;
	}

	public static void printField(List<Document> results, String field) {
		for (Document s : results)
			System.out.println(s.get(field));
	}

	public static void printFields(List<Document> results, String... fields) {
		for (Document s : results) {
			for (String field : fields) {
				System.out.print("[" + field + ": " + s.get(field) + "] ");
			}
			System.out.println();
		}
	}

	public static void printAll(List<Document> results) {
		for (Document d : results) {
			System.out.println(d);
		}
	}

	public void getDocumentMetadata(Document d) {
		FeatureClass fc = FeatureClass.fromValue(d.get("feature_class"));
		System.out.println(fc);
	}

	public String name2CC(String name) {
		if (name.equals("United States"))
			return "US";
		else
			return null;
	}

}
